package org.example.pingpong.controller;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.example.pingpong.domain.dto.EventFormDTO;
import org.example.pingpong.domain.po.Event;
import org.example.pingpong.domain.vo.Result;
import org.example.pingpong.service.EventService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;

/**
 * 赛事管理接口
 */
@Api(tags = "03.赛事管理接口")  // Swagger 文档标签，描述该控制器的功能
@RestController
@RequestMapping("/event")  // 控制器映射路径，所有请求以 /event 开头
@Validated  // 开启校验
public class EventController {

    @Autowired
    private EventService eventService;  // 注入赛事服务，用于进行赛事相关的业务处理

    /**
     * 添加新赛事
     *
     * @param event 提交的赛事数据
     * @return 操作结果
     */
    @ApiOperation("赛事添加接口")
    @PostMapping("/add")
    public Result add(@RequestBody @Valid EventFormDTO event) {
        if(event.getStartTime().compareTo(event.getEndTime()) > 0 || event.getEndTime().compareTo(event.getClearStartTime()) > 0
                || event.getStartTime().compareTo(event.getClearEndTime()) > 0)  return Result.fail(551, "本场时间出现问题");

        LambdaQueryWrapper<Event> Wrapper = new LambdaQueryWrapper<>();
        Wrapper.ge(Event::getClearEndTime, event.getStartTime()).le(Event::getStartTime, event.getClearEndTime());
        List<Event> list = eventService.list(Wrapper);
        if(list.size() > 0) {
            return Result.fail(550, "场地已被占用", list);
        }

        Event add = new Event();  // 创建一个新的赛事对象
        BeanUtils.copyProperties(event, add);  // 将请求体中的数据拷贝到赛事对象
        eventService.save(add);  // 调用服务层保存赛事数据
        return Result.success(null);  // 返回成功的操作结果
    }

    /**
     * 删除指定赛事
     *
     * @param ID 赛事的唯一标识符
     * @return 操作结果
     */
    @ApiOperation("赛事删除接口")
    @DeleteMapping("/delete")
    public Result delete(@RequestParam @NotNull Integer ID) {
        Event delete = new Event();  // 创建一个赛事对象
        delete.setId(ID);  // 设置要删除的赛事ID
        Wrapper wrapper = new UpdateWrapper(delete);  // 创建更新条件
        eventService.remove(wrapper);  // 调用服务层删除赛事
        return Result.success(null);  // 返回成功的操作结果
    }

    /**
     * 获取赛事详情
     *
     * @param ID 赛事ID
     * @return 赛事的详细信息
     */
    @ApiOperation("赛事详情接口")
    @GetMapping("/detail")
    public Result detail(@RequestParam @NotNull Integer ID) {
        Event event = new Event();  // 创建一个赛事对象
        event.setId(ID);  // 设置赛事ID
        Wrapper wrapper = new QueryWrapper(event);  // 创建查询条件
        return Result.success(eventService.getOne(wrapper));  // 获取并返回赛事详情
    }

    /**
     * 编辑赛事信息
     *
     * @param event 更新的赛事信息（来自请求体）
     * @return 更新后的赛事信息
     */
    @ApiOperation("赛事更改接口")
    @PutMapping("/edit")
    public Result edit(@RequestBody EventFormDTO event) {
        if(event.getStartTime().compareTo(event.getEndTime()) > 0 || event.getEndTime().compareTo(event.getClearStartTime()) > 0
                || event.getStartTime().compareTo(event.getClearEndTime()) > 0)  return Result.fail(551, "本场时间出现问题");

        LambdaQueryWrapper<Event> Wrapper = new LambdaQueryWrapper<>();
        Wrapper.ge(Event::getClearEndTime, event.getStartTime()).le(Event::getStartTime, event.getClearEndTime());
        List<Event> list = eventService.list(Wrapper);
        if(list.size() > 0) {
            return Result.fail(550, "场地已被占用", list);
        }

        Event edit = new Event();
        edit.setId(event.getId());  // 设置赛事ID，用于查询原始赛事
        Wrapper wrapper = new UpdateWrapper(edit);  // 创建更新条件

        Event update = new Event();  // 创建一个新的赛事对象用于更新
        BeanUtils.copyProperties(event, update);  // 将请求体中的数据拷贝到更新对象

        eventService.update(update, wrapper);  // 调用服务层更新赛事信息
        return Result.success(eventService.getById(edit.getId()));  // 返回更新后的赛事信息
    }

    /**
     * 获取赛事列表，支持分页
     *
     * @param PAGE 当前页码
     * @param SIZE 每页显示的记录数
     * @return 赛事的分页列表
     */
    @ApiOperation("获取全部赛事列表接口")
    @GetMapping("/list")
    public Result list(@RequestParam Integer PAGE, @RequestParam Integer SIZE) {
        Page<Event> pages = eventService.page(new Page<>(PAGE, SIZE));  // 获取指定页码和大小的赛事列表
        return Result.success(pages.getRecords());  // 返回赛事的分页记录
    }

    /**
     * 获取已结束的赛事列表，支持分页
     * <p>
     * 查询条件为赛事的结束时间小于当前时间
     *
     * @param PAGE 当前页码
     * @param SIZE 每页显示的记录数
     * @return 已结束赛事的分页列表
     */
    @ApiOperation("获取已结束赛事列表接口")
    @GetMapping("/formerevent/list")
    public Result formerevent(@RequestParam Integer PAGE, @RequestParam Integer SIZE) {
        QueryWrapper<Event> wrapper = new QueryWrapper<>();
        wrapper.lt("end_time", new Date());  // 查询结束时间小于当前时间的赛事

        Page<Event> pages = eventService.page(new Page<>(PAGE, SIZE), wrapper);  // 获取符合条件的分页赛事列表
        return Result.success(pages.getRecords());  // 返回已结束赛事的分页记录
    }

    /**
     * 获取正在进行的赛事列表，支持分页
     * <p>
     * 查询条件为赛事的开始时间大于或等于当前时间
     *
     * @param PAGE 当前页码
     * @param SIZE 每页显示的记录数
     * @return 当前赛事的分页列表
     */
    @ApiOperation("获取未开始赛事列表接口")
    @GetMapping("/currentevent/list")
    public Result currentevent(@RequestParam Integer PAGE, @RequestParam Integer SIZE) {
        QueryWrapper<Event> wrapper = new QueryWrapper<>();
        wrapper.ge("start_time", new Date());  // 查询开始时间大于或等于当前时间的赛事

        Page<Event> pages = eventService.page(new Page<>(PAGE, SIZE), wrapper);  // 获取符合条件的分页赛事列表
        return Result.success(pages.getRecords());  // 返回正在进行赛事的分页记录
    }
}
